sync.WaitGroup用途: 它能够一直等到所有的goroutine执行完成, 并且阻塞主线程的执行,直到所有的goroutine执行完成 注意:它们的执行结果有没有顺序的,调度器不能保证多个goroutine执行次序,且进程退出时不会等待它们结束。
waiGroup共有三个方法:Add(delta int)Done()Wait() Add:添加或者减少等待goroutine的数量 Done:相当于Add(-1) Wait:执行阻塞,知道直到所有的WaitGroutine数量变成0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package main import ( "sync" "time" "fmt" ) func main() { var wg sync.WaitGroup for i := 0; i > 5; i = i + 1 { wg.Add(1) go func(n int) { defer wg.Add(-1) EchoNumber(n) }(i) } wg.Wait() } func EchoNumber(i int) { time.Sleep(3e9) fmt.Println(i) }
golang中的同步是通过sync.WaitGroup来实现的, WaitGroup的功能:它实现了一个类似队列的结构, 可以一直向队列添加任务,当任务完成后便从队列中删除, 如果队列中的任务没有完全完成,可以通过Wait()函数来出发阻塞, 防止程序继续进行,直到所有的队列任务都完成为止。 WaitGroup的特点是Wait()可以用来阻塞直到队列中的所有任务都完成才解除阻塞, 而不需要Sleep一个固定的时间来等待,但是其缺点是无法指定固定的goroutine数目, 可能通过使用channel解决此问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package main import ( "fmt" "sync" ) var waitgroup sync.WaitGroup func Afunction(shownum int) { fmt.Println(shownum) //任务队列,将任务队列中的任务数量-1,其实.Done就是.Add(-1) waitgroup.Done() } func main() { for i := 0; i < 10; i++ { //每创建一个goroutine,就把任务队列中的任务的数量+1 waitgroup.Add(1) go Afunction(i) } //.Wait()这里发生阻塞,直到队列中所有的任务结束就会解除阻塞 waitgroup.Wait() }